package mobi.yuanshen.oss;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;


/**
 * 该类主要是把文件存储到服务器上的工具类。
 * 该类提供了将MultipartFile对象上传到服务器的方法。
 * public static String transToServer (String requestUrl,@NonNull MultipartFile file,@NonNull String fileName)方法
 * 提供了一种不经过转存，直接转存到服务器的提交方式，可以节省中专服务器的硬盘和内存资源，较推荐。
 * 需要注意的是transToServer的第一个参数如果不指定的话，
 * 会使用ParamsUtils.FILE_UPLOAD_INTERFACE_URL值作为默认的接口url。
 * @Date 2025-05-23 20:47
 */
@Slf4j
public class FileTransforServer {

    private FileParamsUtils paramsUtils; // 参数工具类

    public FileParamsUtils getParamsUtils() {
        return paramsUtils;
    }

    /**
     * 获取服务器存储路径
     * @return
     */
    public String getServerAddr () {
        return paramsUtils.getFileStorageHttpPath();
    }

    public void setParamsUtils(FileParamsUtils paramsUtils) {
        this.paramsUtils = paramsUtils;
    }

    /**
     * 将流直接向服务器存储，不经过本地转存，直接用这个就好
     * @param requestUrl 文件url
     * @param file MultipartFile文件
     * @param fileName 指定文件名
     * @return 服务器存储成功后返回的文件名
     * @throws IOException
     */
    public String transToServer (String requestUrl,@NonNull MultipartFile file,@NonNull String fileName) throws IOException {
        RestTemplate restTemplate = new RestTemplate(); // 创建template对象
        if (requestUrl == null) { // 若未传递requestUrl的值，则给与默认值
            requestUrl = paramsUtils.FILE_UPLOAD_INTERFACE_URL;
        }
        log.info("请求url:" + requestUrl);
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>(); // 请求体表单
        parts.add("file", new InputStreamResource(file.getInputStream()) {
            // 这里一定要重写这两个方法，不然会报错的
            @Override
            public long contentLength() throws IOException {
                // 返回流的大小
                return file.getSize();
            }

            @Override
            public String getFilename() {
                // 返回文件名
                return fileName;
            }
        });//将数据添加到表单
        HttpHeaders headers = new HttpHeaders(); // 请求头
        headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 设置请求数据的格式为formData
        headers.set("AccessKey",paramsUtils.FileUploadAccessKey);
        HttpEntity httpEntity = new HttpEntity(parts,headers); // 创建http实体对象
        try {
            Result res = restTemplate.postForObject(
                    requestUrl, // 请求url
                    httpEntity, // http请求对象
                    Result.class); // 返回值的类型
            log.info("服务器返回数据 -- >{}", res);
            return res.getData().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
